1 /** 2 Custom assertions for testing unit-threaded itself, not intended for the end-user. 3 */ 4 module unit_threaded.asserts; 5 6 @safe: 7 8 /** 9 * Helper to call the standard assert 10 */ 11 void assertEqual(T, U)(T t, U u, string file = __FILE__, size_t line = __LINE__) @trusted /* std.conv.to */ { 12 import std.conv : to; 13 14 assert(t == u, 15 "\n" ~ file ~ ":" ~ line.to!string ~ "\nExp: " ~ u.to!string ~ "\nGot: " ~ t.to!string); 16 } 17 18 void assertExceptionMsg(E)(lazy E expr, string expected, in string file = __FILE__, 19 in size_t line = __LINE__) { 20 import unit_threaded.should : UnitTestException; 21 import std..string : stripLeft, replace, split; 22 import std.path : dirSeparator; 23 import std.algorithm : map, all, endsWith; 24 import std.range : zip; 25 import std.conv : to, text; 26 import core.exception : AssertError; 27 28 string getExceptionMsg(E)(lazy E expr) { 29 try { 30 expr(); 31 } catch (UnitTestException ex) { 32 return ex.toString; 33 } 34 assert(0, "Expression did not throw UnitTestException"); 35 } 36 37 //updating the tests below as line numbers change is tedious. 38 //instead, replace the number there with the actual line number 39 expected = expected.replace(":123", ":" ~ line.to!string).replace("/", dirSeparator); 40 auto msg = getExceptionMsg(expr); 41 auto expLines = expected.split("\n").map!stripLeft; 42 auto msgLines = msg.split("\n").map!stripLeft; 43 if (!zip(msgLines, expLines).all!(a => a[0].endsWith(a[1]))) { 44 throw new AssertError(text("\nExpected Exception:\n", expected, 45 "\nGot Exception:\n", msg), file, line); 46 } 47 }